const { FFMPEG_V2_PATH, FFMPEG_PATH } = require("./ffmpeg");
const { loadConfig } = require("./config");
const { execSync } = require("child_process");
const fs = require("fs");
const path = require("path");
const config = loadConfig();
const tWidth = config.projectSettings.videoWidth || 1080;
const tHeight = config.projectSettings.videoHeight || 1920;
const transitionsPath = config.transitionsPath;

/**
 * 添加多个音频到视频
 * @param {string} videoContentWithOutAudioPath - 无音频的视频路径
 * @param {Object[]} info - 资源路径数组
 * @param {string}  info.imgPath:
 * @param {string}  info.audioPath:
 * @param {string}  info.wordDuration:
 * @param {string}  info.sentenceImage:
 * @param {string}  info.sentenceAudioPath:
 * @param {string}  info.sentenceDuration:
 * @param {Object} options - 配置选项
 * @param {string} options.outputPath - 输出视频路径
 * @param {string} outputPath - 输出视频路径
 * @returns {string} FFmpeg命令
 */
function addAudioToVideo(videoContentWithOutAudioPath, info, options = {}) {
  console.log("  开始生成添加音频到视频命令...");
  console.log(options.outputPath)
  // 遍历info,在videoContentWithOutAudioPath视频中:
  // 根据info.wordDuration ，插入info.audioPath音频
  // 根据info.sentenceDuration ，插入info.sentenceAudioPath音频
  let durationSum = 0;
  const inputPaths = [`-i "${videoContentWithOutAudioPath}"`];
  const insertFilter = [];
  let audioIndex = 1; // 视频是第0个输入，所以音频从第1个开始
  
  for (let i = 0; i < info.length; i++) { 
    console.log("  开始处理,info：", JSON.stringify(info[i]));
    const wordDuration = info[i].wordDuration;
    if(!wordDuration) process.exit(1);
    const audioPath = info[i].audioPath;
    
    // 添加单词音频输入
    inputPaths.push(`-i "${audioPath}"`);
    
    // 在durationSum处插入单词音频
    insertFilter.push(`[${audioIndex}:a]adelay=${Math.round(durationSum * 1000)}|${Math.round(durationSum * 1000)}[a${audioIndex}]`);
    
    durationSum += wordDuration;
    audioIndex++;
    
    const sentenceDuration = info[i].sentenceDuration;
    if (sentenceDuration && sentenceDuration > 0) {
      const sentenceAudioPath = info[i].sentenceAudioPath;
      // 添加句子音频输入
      inputPaths.push(`-i "${sentenceAudioPath}"`);
      
      // 插入句子音频
      insertFilter.push(`[${audioIndex}:a]adelay=${Math.round(durationSum * 1000)}|${Math.round(durationSum * 1000)}[a${audioIndex}]`);
      
      durationSum += sentenceDuration;
      audioIndex++;
    }
  }
  
  // 创建amix过滤器，混合所有音频轨道
  const mixInputs = [];
  for (let i = 1; i < audioIndex; i++) {
    mixInputs.push(`[a${i}]`);
  }
  const mixFilter = `${mixInputs.join('')}amix=inputs=${audioIndex - 1}:dropout_transition=0[aout]`;
  insertFilter.push(mixFilter);
  
  const insertFilterStr = insertFilter.join(";");
  return `${FFMPEG_PATH} -y ${inputPaths.join(' ')} -filter_complex "${insertFilterStr}" -map 0:v -map "[aout]" -c:v copy -c:a aac -b:a 128k ${options.outputPath}`;
}

/**
 * 预处理视频，添加过渡效果
 * @param {Object[]} info - 资源路径数组
 * @param {string}  imgPath: lessonResource[i].imgPath,
 * @param {string}  wordDuration: lessonResource[i].wordDuration,
 * @param {string}  sentenceImage: lessonResource[i].sentenceRes.imagePath,
 * @param {string}  sentenceDuration:
 * @param {Object} options - 配置选项
 * @param {string} options.outputPath - 输出视频路径
 */
function generatePageFlipVideoCommandV2(info, options = {}) {
  // 设置默认值
  const { outputPath } = options;
  const transitionDuration = 0.5;
  if (!info || info.length === 0) {
    throw new Error("至少需要一张图片");
  }

  if (!outputPath) {
    throw new Error("必须指定输出路径");
  }

  // 构建输入参数
  const inputParams = [];
  const durationParams = [];
  for (let i = 0; i < info.length; i++) {
    inputParams.push(`-i "${info[i].imgPath}"`);
    durationParams.push(`${info[i].wordDuration}`);
    if (!info[i].sentenceImage) continue;
    inputParams.push(`-i "${info[i].sentenceImage}"`);
    durationParams.push(`${info[i].sentenceDuration}`);
  }
  // 为每个输入创建scale、pad、trim和setpts过滤器
  let filterChain = [];
  let j = 0;
  for (let i = 0; i < info.length; i++) {
    filterChain.push(
      `[${j}:v]scale=${tWidth}:${tHeight}:force_original_aspect_ratio=decrease,pad=${tWidth}:${tHeight}:(ow-iw)/2:(oh-ih)/2,setsar=1,trim=duration=${info[i].wordDuration},setpts=PTS-STARTPTS[v${j}]`
    );
    if (!info[i].sentenceImage) {
      j++;
      continue;
    }
    j++;
    filterChain.push(
      `[${j}:v]scale=${tWidth}:${tHeight}:force_original_aspect_ratio=decrease,pad=${tWidth}:${tHeight}:(ow-iw)/2:(oh-ih)/2,setsar=1,trim=duration=${info[i].sentenceDuration},setpts=PTS-STARTPTS[v${j}]`
    );
    j++;
  }

  // 创建转场效果链
  let prevStream = "[v0]"; // 从第一个视频流开始
  let cumOffset = 0; // 累积偏移时间

  // 对每一对图片应用翻页转场效果
  let k = 0;
  let totalDuration = 0;
  for (let i = 0; i < info.length; i++) {
    // 计算偏移量
    const wordDuration = info[i].wordDuration;
    let offset = cumOffset + wordDuration - transitionDuration;
    totalDuration += wordDuration;
    // 使用gltransition过滤器创建翻页效果
    const outputLabel = `[out${k}]`;
    if (k+1 < j) { // j是视频流的总数，确保下一个视频流存在
      const filter = `${prevStream}[v${k+1}]gltransition=duration=${transitionDuration}:offset=${offset}:source='${transitionsPath}/InvertedPageCurl_Final.glsl'${outputLabel}`;
      console.log("filter : ",filter);
      filterChain.push(`${filter}`);
      prevStream = outputLabel;
    }
    k++; // 总是增加k以匹配视频流索引
    
    if (!info[i].sentenceImage) {
      continue;
    }
    
    const sentenceDuration = info[i].sentenceDuration;
    offset = cumOffset + sentenceDuration - transitionDuration;
    if (k+1 < j) { // 确保下一个视频流存在
      const nextOutputLabel = `[out${k}]`;
      filterChain.push(`${prevStream}[v${k+1}]gltransition=duration=${transitionDuration}:offset=${offset}:source='${transitionsPath}/InvertedPageCurl_Final.glsl'${nextOutputLabel}`);
      prevStream = nextOutputLabel;
    }
    k++; // 增加k以匹配视频流索引
    totalDuration += sentenceDuration;
    // 更新累积偏移
    cumOffset += wordDuration + sentenceDuration;
  }

  // 添加最终格式化过滤器
  filterChain.push(`${prevStream}format=yuv420p[vout]`);

  // 完整的过滤器链
  const finalFilterChain = filterChain.join(";");
  const finalFilter = `${finalFilterChain}`;

  return `${FFMPEG_V2_PATH} -y ${inputParams.join(' ')} -analyzeduration 5000000 -probesize 5000000 -filter_complex "${finalFilter}" -map "[vout]" -c:v mpeg4 -q:v 5 -pix_fmt yuv420p -t ${totalDuration} "${outputPath}"`;
}

/**
 * 生成具有翻页效果的视频
 * @param {string[]} imagePaths - 图片路径数组
 * @param {Object} options - 配置选项
 * @param {number} options.durationPerImage - 每张图片显示时长（秒），默认为3秒
 * @param {number} options.transitionDuration - 翻页转场时长（秒），默认为1秒
 * @param {string} options.outputPath - 输出视频路径
 * @returns {string} FFmpeg命令
 */
function generatePageFlipVideo(imagePaths, options = {}) {
  // 设置默认值
  const { durationPerImage = 3, transitionDuration = 1, outputPath } = options;

  if (!imagePaths || imagePaths.length === 0) {
    throw new Error("至少需要一张图片");
  }

  if (!outputPath) {
    throw new Error("必须指定输出路径");
  }

  if (imagePaths.length === 1) {
    // 只有一张图片的情况下，直接创建一个简单的视频
    const cmd = `${FFMPEG_V2_PATH} -y -loop 1 -i "${imagePaths[0]}" -c:v h264_mf -t ${durationPerImage} -pix_fmt yuv420p "${outputPath}"`;
    execSync(cmd, { stdio: 'inherit' });
    return cmd;
  }

  // 获取输出目录
  const outputDir = path.dirname(outputPath);
  const tempFiles = [];

  // 为每对相邻图片创建带转场效果的过渡视频
  for (let i = 0; i < imagePaths.length - 1; i++) {
    const tempOutputPath = path.join(outputDir, `transition_${i}.mp4`);
    tempFiles.push(tempOutputPath);

    // 构建过滤器链
    const filterChain = [
      `[0:v]trim=duration=${durationPerImage},setpts=PTS-STARTPTS[v0]`,
      `[1:v]trim=duration=${durationPerImage},setpts=PTS-STARTPTS[v1]`,
      `[v0][v1]gltransition=source=${transitionsPath}/InvertedPageCurl.glsl:duration=${transitionDuration}`
    ].join(';');

    const cmd = `${FFMPEG_V2_PATH} -y -loop 1 -i "${imagePaths[i]}" -loop 1 -i "${imagePaths[i+1]}" -filter_complex "${filterChain}" "${tempOutputPath}"`;
    console.log("cmd : ==== > ", cmd);
    console.log(`正在创建从第${i}到第${i+1}张图片的过渡视频...`);
    execSync(cmd, { stdio: 'inherit' });
  }

  // 创建concat文件列表
  const concatFilePath = path.join(outputDir, 'transition_list.txt');
  const concatContent = tempFiles.map(file => `file '${path.basename(file)}'`).join('\n');
  fs.writeFileSync(concatFilePath, concatContent);

  // 连接所有过渡视频
  console.log('正在连接所有过渡视频...');
  const concatCmd = `${FFMPEG_PATH} -y -f concat -safe 0 -i "${concatFilePath}" -c copy "${outputPath}"`;
  execSync(concatCmd, { stdio: 'inherit' });

  // 清理临时文件
  console.log('正在清理临时文件...');
  tempFiles.forEach(file => {
    if (fs.existsSync(file)) {
      fs.unlinkSync(file);
    }
  });
  
  if (fs.existsSync(concatFilePath)) {
    fs.unlinkSync(concatFilePath);
  }

  return `已生成视频: ${outputPath}`;
}

module.exports = {
  generatePageFlipVideo,
  generatePageFlipVideoCommandV2,
  addAudioToVideo
};
